module klang.klang.转换工厂.中间码转换.中间码_;
import 全局;
import std.conv: ·to = to;
import std.functional: ·fd = toDelegate;
import ··Klang节点_ = klang.klang.语法节点.Klang节点_;
import ··类型_ = klang.编译.类型.类型_;
import klang.编译.类型.类型_: 基工厂_ = 节点工厂_, 基础符号_ = 符号_, 转换上下文_, 转换函数_, 输出解析器_, 转换支持_, 程序主机接口_, 打印助手_, EmitHint, IEmitTextWriter, 打印机_, 符号表_, 源映射范围_, 文本范围_;
import klang.编译.类型.枚举值.枚举值_: SK;
import klang.编译.输出节点.输出节点_: EmitFlags, addEmitFlags, getOriginalNode_1, setSourceMapRange, addSyntheticLeadingComment;
import klang.编译.语法节点.节点_: 基础节点_ = 节点_, 基础源文件_ = 源文件_, 节点数组_;
import klang.klang.工具.klang工具_: 获取扩展符号标志, 设置节点标志;
import klang.klang.语法节点.Klang节点_: 节点_ = Klang节点_, 源文件_ = Klang源文件_, 标识符_ = Klang标识符_, Klang令牌_, 修饰符_, 语句_, 版本语句_, 表达式_, 块_, 测试单元语句_, 断言语句_, 变量声明_, 导入从版本成员_, 导入版本成员_, 导入成员块_, 导入从成员块_, 导入从成员_, 导入成员_, 程序声明_, 函数声明_, 形参声明_, 对象声明_, 方法声明_, 构建声明_, 如果语句_, 返回语句_, 抛出语句_, 属性声明_, 属性赋值_, 继承子句_, 结构声明节点_ = 结构声明_, 对象声明节点_ = 对象声明_, 调用表达式_, 类型断言表达式_, 符号引用表达式_, 前缀一元表达式_, 二元表达式_, 获取源文件;
import klang.klang.检查.klang检查_: Klang转换支持_, combineTypeMappers, createTypeMapper, instantiateType, instantiateTypes, 获取节点Id, 获取符号Id, 获取类型Id, 获取签名Id, 获取字面量类型的基约束类型, 获取父符号, 创建泛型引用, getTypeArguments, 获取签名从签名声明, getReturnTypeOfSignature, 获取类型节点的类型, 计算类型断言表达式, 获取源文件的程序声明, 获取符号的声明类型;
import klang.klang.类型.klang类型_: 符号_ = Klang符号_, 类型_ = Klang类型_, 签名_ = Klang签名_, KSK, 编译选项_, 节点标志_, 节点扩展_, 类型映射_, 类型标志_, Klang输出种类_, Klang打印选项_, 符号标志_, 复合标志_, klang解析的模块名称_, 内置类型_, 内部符号名_;
import klang.编译.核心.核心_: 词典_, 整数_, 创建数组, 创建词典, 返回零值, 映射, 循环每个, 最小, 获取正规文件名函数_, 查找索引, 结尾包含, 文本包含, 按字符分割, 部分, 连接;
import klang.编译.节点访问.访问节点_: Visitor, visitNode, visitNodes;
import klang.编译.路径.路径_: 获取正规化路径组件组, 获取目录路径, 路径_;
import klang.klang.节点访问.Klang节点访问_: visitEachChild;
import klang.klang.节点工厂.Klang工厂_: 节点工厂标志_, 节点工厂_ = Klang节点工厂_;
import klang.klang.转换工厂.转换工具.Klang转换工具_: 获取输出文件名;
import klang.编译.输出工具.输出工具_: 创建文本写;
import klang.klang.打印输出.Klang打印输出_: 创建打印机 = klang创建打印机;
import klang.编译.工具.工具_: getParseTreeNode_1, 创建符号表;
import klang.klang.转换工厂.中间码转换.类型.中间码类型_: 未整合源文件_, 未整合的泛型源文件_, 实例化内容_, 外部引用类实例化内容_;
import klang.klang.转换工厂.中间码转换.工具.工具_: 初始化工具, 获取符号文本Id, 获取类型文本Id, 获取声明节点的符号, COB_TypeInfo, COB_TypeInfo_Class, COB_Interface, COB_OffsetTypeInfo, COB_ModuleInfo, COB_Object, COB_TypeInfo_vtblZ, COB_D14TypeInfo_Class6__vtblZ, COB_D6Object7__ClassZ, 获取类型引用符号或占位符, 创建类型引用符号占位符, 获取符号引用符号或占位符, 创建符号引用符号占位符, 获取合成节点扩展, 编码输出, 输出编码及长度, 访问节点数组;
import IDec_ = klang.klang.转换工厂.中间码转换.实例化泛型.实例化泛型_;
import klang.编译.编译.编译_: 固定父引用;
import klang.klang.转换工厂.名称碎裂.Mangler_: Mangler, OutBuffer;
源文件_ 当前源文件;
转换上下文_ 当前上下文;
输出解析器_ 输出解析;
Klang转换支持_ K;
编译选项_ 编译选项;
节点工厂_ fc;
程序主机接口_ 主机;
打印机_ 打印机;
类型映射_ 当前映射;
词典_!(实例化内容_) 全局的实例化类型引用;
词典_!(未整合源文件_) 未整合的源文件组;
未整合源文件_ 当前未整合的源文件;
未整合的泛型源文件_ 实例化文件;
节点_[] 当前属性声明组;
dstring[] 当前包名;
long 当前源文件id;
enum 分组_ : int {
    类型声明组_ = 0,
    全局声明组_ = 1,
    函数声明_ = 2,
    函数定义_ = 3
}
转换函数_!(基础节点_) 中间码转换(转换上下文_ ct) {
    .当前上下文 = ct;
    .未整合的源文件组 = 创建词典!(未整合源文件_)();
    .全局的实例化类型引用 = 创建词典!(实例化内容_)();
    .实例化文件 = new 未整合的泛型源文件_();
    .输出解析 = 当前上下文.getEmitResolver();
    .fc = new 节点工厂_(节点工厂标志_.合成工厂_, 节点标志_.Synthesized);
    .K = (cast(Klang转换支持_)(输出解析.获取输出转换支持()));
    初始化工具(.K);
    IDec_.初始环境(.K, .实例化文件, .fc);
    .主机 = 输出解析.获取主机();
    .编译选项 = (cast(编译选项_)(主机.获取编译选项()));
    return cast(转换函数_!(基础节点_))(·fd(&.转换));
}
基础节点_[] 转换(基础节点_ n) {
    .当前源文件 = 获取源文件(n);
    源文件_ 结果 = .转换源文件(.当前源文件);
    if ((当前源文件.标志 & 节点标志_.节点组中最后一个) != 0) {
        设置节点标志(.当前源文件, ~节点标志_.节点组中最后一个);
        if (!实例化文件.是空的()) {
            基础节点_[] 语句组 = 创建数组!(基础节点_)();
            .追加!(基础节点_)(语句组, 实例化文件.类型声明组);
            .追加!(基础节点_)(语句组, 实例化文件.全局声明组);
            .追加!(基础节点_)(语句组, 实例化文件.函数定义组);
            .追加!(基础节点_)(语句组, 实例化文件.函数声明组);
            源文件_ s = fc.创建源文件(fc.f·创建节点数组!(基础节点_)(语句组, false));
            s.输出文件名 = 获取输出文件名((cast(源文件_)(当前未整合的源文件.整合的文件[0])), .主机, .编译选项, ".k4"d);
            if (结果 !is ··null!(源文件_)) {
                return [结果, s];
            }
            return [s];
        }
    }
    if (结果 !is ··null!(源文件_)) {
        固定父引用(结果);
        return [结果];
    }
    return ··null!(基础节点_[]);
}
源文件_ 转换源文件(源文件_ n) {
    程序声明_ 程序声明 = 获取源文件的程序声明(n);
    符号_ 程序符号 = K.获取合并符号(程序声明.符号);
    .当前包名 = 程序符号.碎裂名称;
    dstring ID = 获取符号文本Id(程序符号);
    if (!未整合的源文件组.具有(ID)) {
        未整合的源文件组.p·设置(ID, new 未整合源文件_());
    }
    .当前未整合的源文件 = 未整合的源文件组.获取(ID);
    .当前源文件id = 当前未整合的源文件.整合的文件.length;
    assert(!当前未整合的源文件.源文件组内索引.具有(n.文件名), "源文件多次实例化"c);
    当前未整合的源文件.源文件组内索引.p·设置(n.文件名, .当前源文件id);
    .追加!(源文件_)(当前未整合的源文件.整合的文件, n);
    访问节点数组(n.语句组, cast(Visitor)(·fd(&.访问语句)));
    if (程序符号.声明组.length == 当前未整合的源文件.整合的文件.length) {
        基础节点_[] 语句组 = 创建数组!(基础节点_)();
        .追加!(基础节点_)(语句组, 当前未整合的源文件.类型声明组);
        .追加!(基础节点_)(语句组, 当前未整合的源文件.全局声明组);
        .追加!(基础节点_)(语句组, 当前未整合的源文件.函数定义组);
        .追加!(基础节点_)(语句组, 当前未整合的源文件.函数声明组);
        源文件_ s = fc.创建源文件(fc.f·创建节点数组!(基础节点_)(语句组, false));
        s.输出文件名 = 获取输出文件名((cast(源文件_)(当前未整合的源文件.整合的文件[0])), .主机, .编译选项, ".k2"d);
        s.文件名 = new 路径_(s.输出文件名);
        s.整合的源文件 = 当前未整合的源文件.整合的文件[0 .. $];
        return s;
    }
    return ··null!(源文件_);
}
基础节点_ 访问语句(基础节点_ n) {
    switch (n.目标种类) {
        case KSK.程序声明: {
            return .访问程序声明((cast(程序声明_)(n)));
        }
        case KSK.对象声明: {
            return .访问对象声明((cast(对象声明_)(n)));
        }
        case KSK.属性声明: {
            return .访问属性声明((cast(属性声明_)(n)));
        }
        case KSK.方法声明: {
            return .访问方法声明((cast(方法声明_)(n)));
        }
        default: break;
    }
    return ··null!(基础节点_);
}
基础节点_ 访问程序声明(程序声明_ n) {
    访问节点数组(·to!(节点数组_!(基础节点_))(n.语句组), cast(Visitor)(·fd(&.访问语句)));
    return ··null!(基础节点_);
}
void 创建虚表及同步锁(符号表_ 符号表, ulong L) {
    L = L + 1;
    属性声明_ __vptr = fc.创建属性声明(fc.创建标识符("__vptr"d), fc.创建数组类型(fc.创建指针类型(fc.转为令牌(KSK.无值_)), L));
    符号_ __vptrS = new 符号_((cast(整数_)(符号标志_.属性_)), "__vptr"d);
    __vptrS.类型 = K.创建数组类型(K.获取内置类型(内置类型_.无值指针类型), L);
    __vptrS.值声明 = __vptr;
    __vptrS.声明组 = [__vptr];
    __vptr.符号 = __vptrS;
    .追加!(节点_)(.当前属性声明组, __vptr);
    属性声明_ __monitor = fc.创建属性声明(fc.创建标识符("__monitor"d), fc.创建指针类型(fc.转为令牌(KSK.无值_)));
    符号_ __monitorS = new 符号_((cast(整数_)(符号标志_.属性_)), "__monitor"d);
    __monitorS.类型 = K.获取内置类型(内置类型_.无值指针类型);
    __monitorS.值声明 = __monitor;
    __monitorS.声明组 = [__monitor];
    __monitor.符号 = __monitorS;
    .追加!(节点_)(.当前属性声明组, __monitor);
    符号表.p·设置("__vptr"d, __vptrS);
    符号表.p·设置("__monitor"d, __monitorS);
}
基础节点_ 访问对象声明(对象声明_ n) {
    if ((n.标志 & 节点标志_.是泛型声明_) == 0) {
        符号_ 符号 = 获取声明节点的符号(n);
        基础符号_ 程序符号 = 符号.父符号;
        dstring name = 编码输出(连接(.当前包名, "."d) ~ "."d ~ n.名称.标识符.内容);
        类型_ 声明类型 = 获取符号的声明类型(符号);
        类型_ 基类型 = 声明类型.解析的基类;
        实例化内容_ 基类实例化内容 = .实例化基类(基类型);
        对象声明_ BT = (cast(对象声明节点_)((cast(外部引用类实例化内容_)(基类实例化内容)).TD));
        .当前属性声明组 = 创建数组!(节点_)();
        符号表_ 属性组 = 创建符号表();
        .创建虚表及同步锁(属性组, 声明类型.虚表.length);
        {
            for (int i = 2; i < BT.成员组.length; ++i) {
                属性声明_ p = (cast(属性声明_)(BT.成员组[i]));
                属性组.p·设置(p.符号.名称, p.符号);
                .追加!(节点_)(.当前属性声明组, p);
            }
        }
        类型_[] 接口组 = 声明类型.实现的接口;
        访问节点数组(·to!(节点数组_!(基础节点_))(n.成员组), cast(Visitor)(·fd(&.访问语句)));
        // 更新修饰符
        对象声明_ 类型声明 = fc.创建对象声明(.设置源映射!(标识符_)(fc.创建文本标识符(name), n.名称), fc.f·创建节点数组!(节点_)(.当前属性声明组, false), ··null!(节点数组_!(··Klang节点_.类型形参_)), ··null!(节点数组_!(继承子句_)), n.修饰符);
        .设置前方注释(类型声明, " 合成的注释"d);
        符号_ 新符号;
        if (当前未整合的源文件.源文件本地组.具有(name)) {
            // 可以前向引用
            新符号 = (cast(符号_)(当前未整合的源文件.源文件本地组.获取(name)));
        }
        else {
            新符号 = new 符号_((cast(整数_)(符号标志_.对象_)), name);
            当前未整合的源文件.源文件本地组.p·设置(name, 新符号);
        }
        新符号.标志 |= 符号.标志;
        新符号.值声明 = 类型声明;
        新符号.声明组 = [类型声明];
        类型_ 新声明类型 = new 类型_((cast(整数_)(类型标志_.对象_)));
        新声明类型.符号 = 新符号;
        新声明类型.复合标志 |= 复合标志_.声明成员已经解析_;
        {
            for (int i = 0; i < 当前属性声明组.length; ++i) {
                属性声明_ p = (cast(属性声明_)(当前属性声明组[i]));
                属性组.p·设置(p.符号.名称, p.符号);
            }
        }
        .当前属性声明组 = 创建数组!(节点_)();
        新声明类型.属性组 = 属性组;
        新符号.声明类型 = 新声明类型;
        类型声明.符号 = 新符号;
        当前未整合的源文件.源文件本地组.p·设置(新符号.名称, 新符号);
        .追加!(基础节点_)(当前未整合的源文件.类型声明组, 类型声明);
        .生成VtblZ(声明类型);
        .生成InitZ(声明类型);
        .生成ClassZ(声明类型);
    }
    return ··null!(基础节点_);
}
// 非泛型
void 生成ClassZ(类型_ decT) {
    Mangler m = new Mangler();
    m.碎裂实例化类型(decT);
    dstring chs = m.outString();
    dstring ClassZ = "_D"d ~ chs ~ "7__ClassZ"d;
    ··Klang节点_.类型引用_ TIC = fc.创建类型引用(fc.创建起始限定名(fc.创建文本标识符("object.TypeInfo_Class"d)));
    符号_ TICS = 获取类型引用符号或占位符(当前未整合的源文件.源文件本地组, "object.TypeInfo_Class"d, TIC);
    if (TICS is ··null!(符号_)) {
        类型_ 引用类型 = K.创建站位结构类型();
        创建类型引用符号占位符(当前未整合的源文件.源文件本地组, 符号标志_.结构_, "object.TypeInfo_Class"d, TIC, 引用类型);
    }
    符号引用表达式_ Class6__vtblZ = fc.创建符号引用表达式(fc.创建文本标识符("_D14TypeInfo_Class6__vtblZ"d));
    符号_ Class6__vtblZS = 获取符号引用符号或占位符(当前未整合的源文件.源文件本地组, "_D14TypeInfo_Class6__vtblZ"d, Class6__vtblZ);
    if (Class6__vtblZS is ··null!(符号_)) {
        类型_ T = K.创建指针类型(K.创建数组类型(K.获取内置类型(内置类型_.无值指针类型), K.创建正整数字面量类型(类型标志_.正整数64_, 22)));
        创建符号引用符号占位符(当前未整合的源文件.源文件本地组, 符号标志_.全局变量_, "_D14TypeInfo_Class6__vtblZ"d, Class6__vtblZ, T);
    }
    属性赋值_ __vptr = fc.创建属性赋值(fc.创建标识符("__vptr"d), fc.创建取址表达式(Class6__vtblZ));
    属性赋值_ __monitor = fc.创建属性赋值(fc.创建标识符("__monitor"d), fc.转为令牌(KSK.空值_));
    /**
        __vptr: 无值*[22]*,
        __monitor: 无值*,
        m_init: { i64, i8* },
        name: { i64, i8* },
        vptr : { i64, i8** },
        interfaces: { i64, %object.Interface* },
        base_:  %object.TypeInfo_Class*,
        destructor: i8*,
        classInvariant: void (%object.Object*)*,
        m_flags: i32, __n: [4 x i8], // 旗帜低位
        deallocator: i8*,
        m_offTi: { i64, %object.OffsetTypeInfo* },
        defaultConstructor: void (%object.Object*)*,
        m_RTInfo i8*
     */
    dstring InitZName = "_D"d ~ chs ~ "6__InitZ"d;
    符号引用表达式_ InitZ = fc.创建符号引用表达式(fc.创建文本标识符(InitZName));
    符号_ InitZS = 获取符号引用符号或占位符(当前未整合的源文件.源文件本地组, InitZName, InitZ);
    if (InitZS is ··null!(符号_)) {
        创建符号引用符号占位符(当前未整合的源文件.源文件本地组, 符号标志_.全局变量_, InitZName, InitZ, decT);
    }
    属性赋值_ m_init = fc.创建属性赋值(fc.创建标识符("m_init"d), fc.创建类型转换表达式(fc.创建取址表达式(InitZ), 
    // 应该是数组类型, 计算出对象大小
    // fc.创建数组类型(fc.转为令牌(KSK.正整数8_), 22)
    fc.创建动态数组类型(fc.转为令牌(KSK.正整数8_))));
    对象声明_ n = (cast(对象声明_)((cast(符号_)(decT.符号)).值声明));
    符号_ nameS = .生成文本字面量变量(连接(.当前包名, "."d) ~ "."d ~ n.名称.标识符.内容);
    标识符_ nameStrName = fc.创建文本标识符((cast(变量声明_)(nameS.值声明)).名称.标识符.内容);
    符号引用表达式_ nameV = fc.创建符号引用表达式(nameStrName);
    获取合成节点扩展(nameV).解析类型 = nameS.类型;
    属性赋值_ name = fc.创建属性赋值(fc.创建标识符("name"d), fc.创建取址表达式(nameV));
    ··Klang节点_.动态类字面量表达式_ DecInit = fc.创建动态类字面量表达式(·to!(节点数组_!(节点_))(fc.f·创建节点数组!(属性赋值_)([__vptr, __monitor, m_init, name], false)), false);
    符号_ 匿名符号 = new 符号_((cast(整数_)(符号标志_.结构字面量_)), 内部符号名_.对象_);
    匿名符号.值声明 = DecInit;
    DecInit.符号 = 匿名符号;
    匿名符号.成员 = 创建符号表();
    .生成属性赋值(匿名符号.成员, __vptr, K.创建指针类型(K.创建数组类型(K.获取内置类型(内置类型_.无值指针类型), K.创建正整数字面量类型(类型标志_.正整数64_, 22))));
    .生成属性赋值(匿名符号.成员, __monitor, K.获取内置类型(内置类型_.无值指针类型));
    .生成属性赋值(匿名符号.成员, m_init, K.创建动态数组类型(K.获取内置类型(内置类型_.正整数8类型)));
    .生成属性赋值(匿名符号.成员, name, K.创建动态数组类型(K.获取内置类型(内置类型_.字符8类型)));
    变量声明_ ClassZDec = fc.创建变量声明(fc.创建文本标识符(ClassZ), TIC, DecInit);
    .生成变量声明(ClassZDec, 获取合成节点扩展(TIC).解析类型);
}
符号_ 生成文本字面量变量(dstring 内容) {
    ulong L = 0;
    dstring nameStr = 输出编码及长度(内容, L) ~ "\\00"d;
    L = L + 1;
    ··Klang节点_.数组类型_ TN = fc.创建数组类型(fc.转为令牌(KSK.字符8_), L);
    dstring nameStrName = .输出文本变量名称(nameStr);
    变量声明_ nameStrN = fc.创建变量声明(fc.创建标识符(nameStrName), TN, fc.创建文本字面量(nameStr, 节点标志_.C));
    类型_ T = K.创建数组类型(K.获取内置类型(内置类型_.字符8类型), L);
    .生成变量声明(nameStrN, T, false, [(cast(修饰符_)(fc.转为令牌(KSK.私有_)))]);
    return (cast(符号_)(nameStrN.符号));
}
void 生成InitZ(类型_ decT) {
    Mangler m = new Mangler();
    m.碎裂实例化类型(decT);
    dstring chs = m.outString();
    dstring InitZName = "_D"d ~ chs ~ "6__InitZ"d;
    对象声明_ n = (cast(对象声明_)((cast(符号_)(decT.符号)).值声明));
    dstring Tname = 编码输出(连接(.当前包名, "."d) ~ "."d ~ n.名称.标识符.内容);
    ··Klang节点_.类型引用_ T = fc.创建类型引用(fc.创建起始限定名(fc.创建文本标识符(Tname)));
    获取合成节点扩展(T).解析类型 = decT;
    变量声明_ InitDec = fc.创建变量声明(fc.创建文本标识符(InitZName), T, fc.创建标识符("{}"d));
    符号_ InitDecS;
    if (当前未整合的源文件.源文件本地组.具有(InitZName)) {
        // 可以前向引用
        InitDecS = (cast(符号_)(当前未整合的源文件.源文件本地组.获取(InitZName)));
    }
    else {
        InitDecS = new 符号_((cast(整数_)(符号标志_.全局变量_)), InitZName);
        当前未整合的源文件.源文件本地组.p·设置(InitZName, InitDecS);
    }
    .生成变量声明(InitDec, decT, false);
}
void 生成VtblZ(类型_ decT) {
    Mangler m = new Mangler();
    m.碎裂实例化类型(decT);
    dstring chs = m.outString();
    dstring VtblZName = "_D"d ~ chs ~ "6__vtblZ"d;
    ··Klang节点_.数组类型_ TN = fc.创建数组类型(fc.创建指针类型(fc.转为令牌(KSK.无值_)), fc.创建字面量类型(fc.创建数字字面量(5, 节点标志_.无)));
    类型_ T = K.创建数组类型(K.获取内置类型(内置类型_.无值指针类型), K.创建正整数字面量类型(类型标志_.正整数64_, 5));
    变量声明_ VtblZDec = fc.创建变量声明(fc.创建文本标识符(VtblZName), TN, fc.创建标识符("{}"d));
    .生成变量声明(VtblZDec, T, false);
}
void 生成变量声明(变量声明_ Dec, 类型_ decT, bool 是变量 = true, 修饰符_[] 修饰符 = ··null!(修饰符_[])) {
    符号_ S;
    dstring name = Dec.名称.标识符.内容;
    if (当前未整合的源文件.源文件本地组.具有(name)) {
        S = (cast(符号_)(当前未整合的源文件.源文件本地组.获取(name)));
    }
    else {
        S = new 符号_((cast(整数_)(符号标志_.全局变量_)), name);
        当前未整合的源文件.源文件本地组.p·设置(name, S);
    }
    if (修饰符 !is ··null!(修饰符_[])) {
        long f = 0;
        foreach (修饰符_ m; 修饰符) {
            f |= (cast(整数_)(获取扩展符号标志(m.目标种类)));
        }
        S.标志 |= f;
    }
    S.标志 &= (cast(整数_)(~符号标志_.符号占位符_));
    S.值声明 = Dec;
    S.声明组 = [Dec];
    S.类型 = decT;
    Dec.符号 = S;
    ··Klang节点_.变量声明列表_ VL = fc.创建变量声明列表(fc.f·创建节点数组!(变量声明_)([Dec], false));
    if (是变量) {
        VL.标志 |= (cast(整数_)(节点标志_.Let));
    }
    else {
        VL.标志 |= (cast(整数_)(节点标志_.Const));
    }
    Dec.父节点 = VL;
    修饰符 ? .追加!(基础节点_)(当前未整合的源文件.全局声明组, fc.创建变量声明语句(VL, fc.f·创建节点数组!(修饰符_)(修饰符, false))) : .追加!(基础节点_)(当前未整合的源文件.全局声明组, fc.创建变量声明语句(VL));
}
void 生成属性赋值(符号表_ 表, 属性赋值_ Dec, 类型_ T) {
    符号_ S;
    dstring name = Dec.名称.标识符.内容;
    if (表.具有(name)) {
        S = (cast(符号_)(表.获取(name)));
    }
    else {
        S = new 符号_((cast(整数_)(符号标志_.属性_)), name);
        表.p·设置(name, S);
    }
    S.标志 &= (cast(整数_)(~符号标志_.符号占位符_));
    S.值声明 = Dec;
    S.声明组 = [Dec];
    S.类型 = T;
    Dec.符号 = S;
}
基础节点_ 访问构建声明(构建声明_ n) {
    return ··null!(基础节点_);
}
基础节点_ 访问方法声明(方法声明_ n) {
    return ··null!(基础节点_);
}
基础节点_ 访问属性声明(属性声明_ n) {
    符号_ 符号 = 获取声明节点的符号(n);
    if ((符号.标志 & 符号标志_.静态_) != 0) {
    }
    else {
        基础节点_ 类型 = .访问类型节点(n.类型);
        .追加!(节点_)(.当前属性声明组, .更新节点!(属性声明_)(n, n));
    }
    return ··null!(基础节点_);
}
基础节点_ 访问类型节点(节点_ n) {
    类型_ 类型 = 获取类型节点的类型(n);
    return n;
}
基础节点_ 访问每个子(基础节点_ n, Visitor v) {
    return visitEachChild!(基础节点_)(n, cast(Visitor)(v), .fc);
}
实例化内容_ 实例化基类(类型_ Bt) {
    if ((Bt.复合标志 & 复合标志_.泛型引用_) != 0) {
        return IDec_.实例化泛型基类(Bt);
    }
    else {
        dstring id = 获取类型文本Id(Bt);
        if (!全局的实例化类型引用.具有(id)) {
            外部引用类实例化内容_ 内容 = new 外部引用类实例化内容_();
            .填充引用实例化内容(内容, Bt);
            全局的实例化类型引用.p·设置(id, 内容);
        }
        return 全局的实例化类型引用.获取(id);
    }
}
void 填充引用实例化内容(外部引用类实例化内容_ 内容, 类型_ T) {
    类型_ 全局对象类型 = K.获取内置类型(内置类型_.全局对象类型);
    if (T == 全局对象类型) {
        .实例化全局文件内容(内容);
    }
}
void 实例化全局文件内容实现(外部引用类实例化内容_ 内容, dstring 名称) {
    符号表_ 表 = 当前未整合的源文件.源文件本地组;
    分组_ 组 = 分组_.类型声明组_;
    bool 存在 = 表.具有(名称);
    基础符号_ S;
    if (存在) {
        S = 表.获取(名称);
        if ((S.标志 & 符号标志_.符号占位符_) == 0) {
            switch (名称) {
                case "object.Object"d: {
                    内容.TD = S.值声明;
                    break;
                }
                case "_D14TypeInfo_Class6__vtblZ"d: {
                    内容.VtblZ = S.值声明;
                    break;
                }
                case "_D6Object7__ClassZ"d: {
                    内容.ClassZ = S.值声明;
                    break;
                }
                default: break;
            }
            return;
        }
    }
    switch (名称) {
        case "object.TypeInfo"d: {
            S = COB_TypeInfo(表);
            break;
        }
        case "object.TypeInfo_Class"d: {
            S = COB_TypeInfo_Class(表);
            break;
        }
        case "object.Interface"d: {
            S = COB_Interface(表);
            break;
        }
        case "object.OffsetTypeInfo"d: {
            S = COB_OffsetTypeInfo(表);
            break;
        }
        case "object.Object"d: {
            S = COB_Object(表);
            内容.TD = S.值声明;
            break;
        }
        case "_D14TypeInfo_Class6__vtblZ"d: {
            S = COB_D14TypeInfo_Class6__vtblZ(表);
            内容.VtblZ = S.值声明;
            组 = 分组_.全局声明组_;
            break;
        }
        case "_D6Object7__ClassZ"d: {
            S = COB_D6Object7__ClassZ(表);
            内容.ClassZ = S.值声明;
            组 = 分组_.全局声明组_;
            break;
        }
        default: break;
    }
    基础节点_ 语句节点 = S.值声明;
    if ((S.标志 & 符号标志_.全局变量_) != 0) {
        语句节点 = S.值声明.父节点.父节点;
    }
    switch (组) {
        case 分组_.类型声明组_: {
            .追加!(基础节点_)(当前未整合的源文件.类型声明组, 语句节点);
            break;
        }
        case 分组_.全局声明组_: {
            .追加!(基础节点_)(当前未整合的源文件.全局声明组, 语句节点);
            break;
        }
        case 分组_.函数声明_: {
            .追加!(基础节点_)(当前未整合的源文件.函数声明组, 语句节点);
            break;
        }
        case 分组_.函数定义_: {
            .追加!(基础节点_)(当前未整合的源文件.函数定义组, 语句节点);
            break;
        }
        default: break;
    }
}
void 实例化全局文件内容(外部引用类实例化内容_ 内容) {
    // 类型:
    .实例化全局文件内容实现(内容, "object.TypeInfo"d);
    .实例化全局文件内容实现(内容, "object.TypeInfo_Class"d);
    .实例化全局文件内容实现(内容, "object.Interface"d);
    .实例化全局文件内容实现(内容, "object.OffsetTypeInfo"d);
    .实例化全局文件内容实现(内容, "object.Object"d);
    // 全局变量:
    .实例化全局文件内容实现(内容, "_D14TypeInfo_Class6__vtblZ"d);
}
T 更新节点(T)(基础节点_ n, T xn) {
    xn.源文件id = .当前源文件id;
    xn.标志 |= (cast(整数_)(节点标志_.Synthesized));
    return (cast(T)(fc.更新(n, xn)));
}
dstring 输出文本变量名称(dstring 内容) {
    if (当前未整合的源文件.文本字面量Id.具有(内容)) {
        return 当前未整合的源文件.文本字面量Id.获取(内容);
    }
    dstring name = ".str"d;
    const(size_t) p = 当前未整合的源文件.文本字面量Id.大小();
    if (p != 0) {
        name ~= "."d ~ ·to!(dstring)(p);
    }
    当前未整合的源文件.文本字面量Id.p·设置(内容, name);
    return name;
}
T 设置源映射(T)(T node, 源映射范围_ re = ··null!(源映射范围_)) {
    if (re !is ··null!(源映射范围_)) {
        re.source = .当前源文件;
    }
    else {
        node.source = .当前源文件;
    }
    基础节点_ n = setSourceMapRange(node, re);
    return (cast(T)(n));
}
void 设置前方注释(节点_ n, dstring 内容) {
    addSyntheticLeadingComment(n, SK.单行注释, 内容, true);
}
